package com.bbz.spring.config;

import com.bbz.core.designpatterns.work2.ColorFactory;
import com.bbz.spring.Conditional.LinuxConditional;
import com.bbz.spring.Conditional.WindowsConditional;
import com.bbz.spring.bean.Color;
import com.bbz.spring.bean.ColorFactoryBean;
import com.bbz.spring.bean.People;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
/**
 * 给容器中注册组件的方式
 * 1：ComponentScan包扫描+标注注解(@Controller,@Service,@Repository,@Component)[自己写的类，用这种方式注册组件]
 * 2：@Bean[导入的第三方包的组件]
 * 3：@Import[快速给容器中导入组件] 导入到容器后，默认Id是类的全类名例如，com.bbz.spring.bean.Color
 * 4：@ImportSelector 通过实现ImportSelector接口，批量导入Bean,默认Id是类的全类名
 * 5:@ImportBeanDefinitionRegistrar 通过实现ImportBeanDefinitionRegistrar接口，可以自定义导入Bean,Bean Id可以自己指定
 * 6:使用Spring Factory Bean注册组件,
 *          默认获取的Bean是FactoryBean接口中getObject()返回的Bean,
 *          要想获取FactryBean接口的实现类的Bean,需要在获取的Bean的时候,在id前加一个&符号
 *          例如：applicationContext.getBean("&colorFactoryBean")
 *
 */
@Configuration
@Import({MyImportSelector.class,MyImportBeanDefinitionRegistrar.class})
public class MainConfig2 {
    /*
        Scope("prototype") 多实例 在IOC容器启动时，并不会创建对象， 而是在每次获取的时候都会创建实例
        Scope("singleton") 默认 单实例 IOC  容器启动时，就将Bean到容器中。
        Scope("request") 同一个请求
        Scope("session") 同一个session
    */
    @Scope //作用域
    @Bean
    public People people(){
        return new People("张四",12);
    }

    /**
     * Lazy 懒加载，要在Scope为单例时，才有效。
     * 当IOC容器启动时不加载Bean,当第一次调用时创建Bean,并加载到IOC容器中。
     * @return
     */
    @Lazy
    @Bean("people1")
    public People people1(){
        return new People("张四",12);
    }

    /**
     * @Conditional 按照一定的条件进行判断，满足条件进行容器注册
     * @Conditional 可配置在类上,也可以配置在方法上
     * @Target({ElementType.TYPE, ElementType.METHOD})
     */
    @Conditional(WindowsConditional.class)
    @Bean("zhangwu")
    public People people2(){
        return new People("张五",12);
    }

    @Conditional(LinuxConditional.class)
    @Bean("zhangliu")
    public People people3(){
        return new People("张六",12);
    }


    @Bean
    public ColorFactoryBean colorFactoryBean(){
        return new ColorFactoryBean("Green");
    }
}
